home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Lib / addr / ap_p2s.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  14.1 KB  |  685 lines

  1. /* ap_p2s.c: convert parts to a string */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Lib/addr/RCS/ap_p2s.c,v 6.0 1991/12/18 20:21:24 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Lib/addr/RCS/ap_p2s.c,v 6.0 1991/12/18 20:21:24 jpo Rel $
  9.  *
  10.  * $Log: ap_p2s.c,v $
  11.  * Revision 6.0  1991/12/18  20:21:24  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. /*
  19. Format one address from pointers to constitutents, in a tree
  20.     Returns:    pointer to string if successful or
  21.     NOTOK if error
  22.  
  23.     Using ap_p2s as output for ap_t2s has the general problem
  24.     of losing comments.   Perhaps ap_t2s should be  separate?
  25. */
  26.  
  27.  
  28.  
  29. #include "util.h"
  30. #include "chan.h"
  31. #include "ap.h"
  32.  
  33. static ap_compress_local();
  34.  
  35. extern int      ap_outtype;
  36.  
  37. extern void      ad_val2str ();
  38.  
  39. /* ---------------------  Begin  Routines  -------------------------------- */
  40.  
  41. static char    *ap_p2s_aux();
  42.  
  43. char *ap_p2s(group, name, local, domain, route)
  44. AP_ptr    group,
  45.     name,
  46.     local,
  47.     domain,
  48.     route;
  49. {
  50.     return ap_p2s_aux (group, name, local, domain, route, TRUE);
  51. }
  52.  
  53. char *ap_p2s_nc(group, name, local, domain, route)
  54. AP_ptr    group,
  55.     name,
  56.     local,
  57.     domain,
  58.     route;
  59. {
  60.     return ap_p2s_aux (group, name, local, domain, route, FALSE);
  61. }
  62.  
  63.  
  64. static char *ap_p2s_aux (group, name, local, domain, route, comments)
  65. AP_ptr                  group,          /* -- start of group name -- */
  66.             name,           /* -- start of person name -- */
  67.             local,          /* -- start of local-part -- */
  68.             domain,         /* -- basic domain ref -- */
  69.             route;          /* -- start of 733 forw routing -- */
  70. int            comments;
  71. {
  72.  
  73.     AP_ptr          last_ptr;
  74.     char            *route_ptr,     /* -- 822 -> 733 route ptr */
  75.             *flip_ptr, *subdom = NULLCP,
  76.             *dref_ptr,      /* -- ptr to output str -- */
  77.             tmpbuf [BUFSIZ],
  78.             buf[BUFSIZ];  /* -- buf for tb_getdomain -- */
  79.     int             in_person,
  80.             in_group,
  81.             last,
  82.             after_comment;
  83.     register AP_ptr cur_ptr = NULLAP;
  84.     register char   *s_ptr,         /* -- the str we are building -- */
  85.             *c_ptr;
  86.  
  87.  
  88.     PP_DBG (("Lib/adr/ap_p2s()"));
  89.  
  90.     PP_DBG (("Lib/addr/ap_p2s/AP_PARSE_822 %s",
  91.                 ap_outtype & AP_PARSE_822?"on":"off"));
  92.  
  93.     PP_DBG (((ap_outtype & AP_PARSE_BIG) ?
  94.                 "AP_PARSE_BIG on" : "AP_PARSE_LITTLE on"));
  95.  
  96.  
  97.     in_person       = FALSE;
  98.     in_group        = FALSE;
  99.     s_ptr           = strdup ("");
  100.     route_ptr       = strdup ("");
  101.     last        = AP_NIL;
  102.     after_comment    = FALSE;
  103.  
  104.     if (!comments)
  105.         ap_compress_local(group,name,local,domain,route,comments);
  106.         
  107.     if (group != NULLAP) {
  108.  
  109.         PP_DBG (("Lib/addr/ap_p2s:  group is '%s'",
  110.                 group -> ap_obvalue));
  111.  
  112.         for (cur_ptr = group; cur_ptr != NULLAP;
  113.              cur_ptr = cur_ptr->ap_next) {
  114.  
  115.             if (cur_ptr == name || cur_ptr == local ||
  116.                 cur_ptr == domain || cur_ptr == route)
  117.                 break;
  118.  
  119.             /* -- print munged addr -- */
  120.  
  121.             switch (cur_ptr -> ap_obtype) {
  122.             default:
  123.             case AP_NIL:
  124.                 break;
  125.  
  126.             case AP_COMMENT:
  127.                 if (comments == TRUE) {
  128.                     /* -- output value as comment -- */
  129.                     ap_val2str (tmpbuf,
  130.                             cur_ptr -> ap_obvalue,
  131.                             AP_COMMENT);
  132.  
  133.                     c_ptr = multcat (s_ptr,
  134.                              (s_ptr[0]?" ":""),
  135.                              "(",
  136.                              tmpbuf,
  137.                              ")",
  138.                              NULLCP);
  139.                     free (s_ptr);
  140.                     if (c_ptr == NULLCP)
  141.                         return ((char *)NOTOK);
  142.                     s_ptr = c_ptr;
  143.                     after_comment = TRUE;
  144.                 }
  145.                 continue;
  146.  
  147.             case AP_GROUP_NAME:
  148.                 in_group = TRUE;
  149.  
  150.             case AP_GROUP_START:
  151.                 ap_val2str (tmpbuf,
  152.                     cur_ptr -> ap_obvalue,
  153.                     AP_GROUP_START);
  154.                 c_ptr = multcat (s_ptr, 
  155.                          (((s_ptr[0]&&last==AP_GROUP_START) || after_comment == TRUE)?" ":""),
  156.                          tmpbuf, NULLCP);
  157.                 free (s_ptr);
  158.                 if (c_ptr == NULLCP)
  159.                     return ((char *)NOTOK);
  160.                 s_ptr = c_ptr;
  161.                 last = AP_GROUP_START;
  162.                 after_comment = FALSE;
  163.                 continue;
  164.             }
  165.  
  166.             break;
  167.         }
  168.  
  169.  
  170.         if (in_group) {
  171.             c_ptr = multcat (s_ptr, ":", NULLCP);
  172.             free (s_ptr);
  173.             if (c_ptr == NULLCP)
  174.                 return ((char *)NOTOK);
  175.             s_ptr = c_ptr;
  176.             /* need space after this yuch */
  177.             after_comment = TRUE;
  178.         }
  179.     }
  180.  
  181.  
  182.  
  183.     if (name != NULLAP) {
  184.         PP_DBG (("LIb/addr/ap_p2s:  name is '%s'",
  185.                 name -> ap_obvalue));
  186.  
  187.         for (cur_ptr = name; cur_ptr != NULLAP;
  188.              cur_ptr = cur_ptr -> ap_next) {
  189.             
  190.             if (cur_ptr == group || cur_ptr == local ||
  191.                 cur_ptr == domain || cur_ptr == route)
  192.                 break;
  193.  
  194.             /* -- print munged addr -- */
  195.             switch (cur_ptr -> ap_obtype) {
  196.             default:
  197.             case AP_NIL:
  198.                 break;
  199.  
  200.             case AP_COMMENT:
  201.                 if (comments == TRUE) {
  202.                     /* -- output value as comment -- */
  203.                     ap_val2str (tmpbuf,
  204.                             cur_ptr -> ap_obvalue,
  205.                             AP_COMMENT);
  206.  
  207.                     c_ptr = multcat (s_ptr,
  208.                              (s_ptr[0]?" " : ""),
  209.                              "(",
  210.                              tmpbuf,
  211.                              ")",
  212.                              NULLCP);
  213.                     free (s_ptr);
  214.                     if (c_ptr == NULLCP)
  215.                         return ((char *)NOTOK);
  216.                     s_ptr = c_ptr;
  217.                     after_comment = TRUE;
  218.                 }
  219.                 continue;
  220.  
  221.             case AP_PERSON_NAME:
  222.                 in_person = TRUE;
  223.  
  224.             case AP_PERSON_START:
  225.                 ap_val2str (tmpbuf,
  226.                     cur_ptr -> ap_obvalue,
  227.                     AP_PERSON_START);
  228.                 c_ptr = multcat (s_ptr, 
  229.                          (((s_ptr[0] && last == AP_PERSON_START) || after_comment == TRUE)?" ":""),
  230.                          tmpbuf, NULLCP);
  231.                 free (s_ptr);
  232.                 if (c_ptr == NULLCP)
  233.                     return ((char *)NOTOK);
  234.                 s_ptr = c_ptr;
  235.                 last = AP_PERSON_START;
  236.                 after_comment = FALSE;
  237.                 continue;
  238.             }
  239.  
  240.             break;
  241.         }
  242.     }
  243.  
  244.  
  245.  
  246.     if (in_person) {
  247.         c_ptr = multcat (s_ptr, " <", NULLCP);
  248.         free (s_ptr);
  249.         if (c_ptr == NULLCP)
  250.             return ((char *)NOTOK);
  251.         s_ptr = c_ptr;
  252.         after_comment = FALSE;
  253.     }
  254.  
  255.  
  256.  
  257.     if (route != NULLAP) {
  258.         /* -- routing info exits -- */
  259.         PP_DBG (("Lib/addr/ap_p2s:  route is '%s'",
  260.                 route -> ap_obvalue));
  261.  
  262.         for (last_ptr = cur_ptr = route; ;
  263.              cur_ptr = cur_ptr -> ap_next) {
  264.  
  265.             /* -- grot grot !!!!!!! -- */
  266.             if (cur_ptr == NULLAP)
  267.                 goto defcase1;
  268.  
  269.             switch (cur_ptr -> ap_obtype) {
  270.             case AP_PERSON_END:
  271.                 continue;
  272.  
  273.             defcase1:;
  274.                 /* yeuch !! */
  275.             default:
  276.  
  277.             case AP_NIL:
  278.                 if ((ap_outtype & AP_PARSE_822) ==
  279.                      AP_PARSE_822) {
  280.                     /* -- piece of cake -- */
  281.                     c_ptr = multcat (s_ptr, ":", NULLCP);
  282.                     free (s_ptr);
  283.                     if (c_ptr == NULLCP)
  284.                         return ((char *)NOTOK);
  285.                     s_ptr = c_ptr;
  286.                 }
  287.                 break;
  288.  
  289.             case AP_COMMENT:
  290.                 if (comments == TRUE) {
  291.                     /* -- output value as comment -- */
  292.                     ap_val2str (tmpbuf,
  293.                             cur_ptr -> ap_obvalue,
  294.                             AP_COMMENT);
  295.                     after_comment = TRUE;
  296.                     c_ptr = multcat (s_ptr,
  297.                              (s_ptr[0]?" ":""),
  298.                              "(",
  299.                              tmpbuf,
  300.                              ")",
  301.                              NULLCP);
  302.                     free (s_ptr);
  303.                     if (c_ptr == NULLCP)
  304.                         return ((char *)NOTOK);
  305.                     s_ptr = c_ptr;
  306.                 }
  307.                 continue;
  308.  
  309.  
  310.             case AP_DOMAIN_LITERAL:
  311.             case AP_DOMAIN:
  312.                 ap_val2str (tmpbuf,
  313.                     cur_ptr -> ap_obvalue,
  314.                     cur_ptr -> ap_obtype);
  315.                 flip_ptr = NULLCP;
  316.                 dref_ptr = tmpbuf;
  317.  
  318.                 /* -- only flip valid domains -- */
  319.                 if ((ap_outtype & AP_PARSE_BIG) ==
  320.                      AP_PARSE_BIG &&
  321.                      tb_getdomain (tmpbuf, NULLCP,
  322.                            buf,
  323. #ifdef UKORDER
  324.                            CH_UK_PREF,
  325. #else
  326.                            CH_USA_PREF,
  327. #endif
  328.                            &subdom) == OK) {
  329.                     /* -- usa ordering preferred -- */
  330.                     flip_ptr = ap_dmflip (buf);
  331.                     dref_ptr = flip_ptr;
  332.                 }
  333.                 if (subdom != NULLCP) {    
  334.                     free(subdom);subdom=NULLCP;
  335.                 }
  336.                 if ((ap_outtype & AP_PARSE_822) ==
  337.                      AP_PARSE_822) {
  338.                     /* -- piece of cake -- */
  339.                     c_ptr = multcat (
  340.                         s_ptr,
  341. /*                        (((s_ptr[0] && last == AP_DOMAIN) || after_comment == TRUE)?" ":""),*/
  342.                         ((after_comment == TRUE)?" ":""),
  343.                         (cur_ptr!=last_ptr?",@":"@"),
  344.                         dref_ptr,
  345.                         NULLCP);
  346.                     free (s_ptr);
  347.                     if (c_ptr == NULLCP)
  348.                         return ((char *)NOTOK);
  349.                     last = AP_DOMAIN;
  350.                     after_comment = FALSE;
  351.                     s_ptr = c_ptr;
  352.                 }
  353.                 else {
  354.                     if (route_ptr[0] == '\0')
  355.                         c_ptr = multcat (
  356.                             "@",
  357.                             dref_ptr,
  358.                             NULLCP);
  359.                     else
  360.                         c_ptr = multcat (
  361.                             "%",
  362.                             dref_ptr,
  363.                             route_ptr,
  364.                             NULLCP);
  365.                     free (route_ptr);
  366.                     if (c_ptr == NULLCP)
  367.                         return ((char *)NOTOK);
  368.                     route_ptr = c_ptr;
  369.                 }
  370.  
  371.                 if (flip_ptr != NULLCP)
  372.                     free (flip_ptr);
  373.                 continue;
  374.             }
  375.  
  376.             break;
  377.         }
  378.     }
  379.  
  380.  
  381.     if (local != NULLAP) {
  382.         PP_DBG (("LIb/addr/ap_p2s:  local is '%s'",
  383.                 local -> ap_obvalue));
  384.  
  385.         for (cur_ptr = local; cur_ptr != NULLAP;
  386.              cur_ptr = cur_ptr -> ap_next) {
  387.  
  388.             if (cur_ptr == group || cur_ptr == name ||
  389.                 cur_ptr == domain || cur_ptr == route)
  390.                 break;
  391.             /* -- print munged addr -- */
  392.             switch (cur_ptr -> ap_obtype) {
  393.             default:
  394.             case AP_NIL:
  395.                 break;
  396.  
  397.             case AP_COMMENT:
  398.                 if (comments == TRUE) {
  399.                     /* -- don't skip these -- */
  400.                     ap_val2str (tmpbuf,
  401.                             cur_ptr -> ap_obvalue,
  402.                             AP_COMMENT);
  403.  
  404.                     c_ptr = multcat (s_ptr,
  405.                              (s_ptr[0]?" ":""),
  406.                              "(",
  407.                              tmpbuf,
  408.                              ")",
  409.                              NULLCP);
  410.                     free (s_ptr);
  411.                     if (c_ptr == NULLCP)
  412.                         return ((char *)NOTOK);
  413.                     s_ptr = c_ptr;
  414.                     after_comment = TRUE;
  415.                 }
  416.                 continue;
  417.  
  418.             case AP_GENERIC_WORD:
  419.             case AP_MAILBOX:
  420.                 /* -- yuk -- */
  421.                 ap_val2str (tmpbuf,
  422.                     cur_ptr -> ap_obvalue,
  423.                     AP_MAILBOX);
  424.                 c_ptr = multcat (s_ptr, 
  425.                          (((s_ptr[0]&&last==AP_MAILBOX) || after_comment == TRUE)?" ":""),
  426.                          tmpbuf, NULLCP);
  427.                 free (s_ptr);
  428.                 if (c_ptr == NULLCP)
  429.                     return ((char *)NOTOK);
  430.                 s_ptr = c_ptr;
  431.                 last = AP_MAILBOX;
  432.                 after_comment = FALSE;
  433.                 continue;
  434.             }
  435.  
  436.             break;
  437.         }
  438.     }
  439.  
  440.  
  441.  
  442.     if (domain != NULLAP) {
  443.         PP_DBG (("Lib/addr/ap_p2s:  domain is '%s'",
  444.                 domain -> ap_obvalue));
  445.  
  446.         for (cur_ptr = domain; cur_ptr != NULLAP;
  447.              cur_ptr = cur_ptr->ap_next) {
  448.             
  449.             if (cur_ptr == group || cur_ptr == name ||
  450.                 cur_ptr == local || cur_ptr == route)
  451.                 break;
  452.             switch (cur_ptr->ap_obtype) {
  453.                 default:
  454.                 case AP_NIL:
  455.                 break;
  456.  
  457.                 case AP_COMMENT:
  458.                 if (comments == TRUE) {
  459.                     ap_val2str(tmpbuf,
  460.                            cur_ptr->ap_obvalue,
  461.                            AP_COMMENT);
  462.                     c_ptr = multcat (s_ptr,
  463.                              (s_ptr[0]?" ":""),
  464.                              "(",
  465.                              tmpbuf,
  466.                              ")",
  467.                              NULLCP);
  468.                     free (s_ptr);
  469.                     if (c_ptr == NULLCP)
  470.                         return ((char *)NOTOK);
  471.                     s_ptr = c_ptr;
  472.                     after_comment = TRUE;
  473.                 }
  474.                 continue;
  475.                 
  476.                 case AP_DOMAIN:
  477.                 ap_val2str (tmpbuf, domain -> ap_obvalue, domain -> ap_obtype);
  478.                 flip_ptr = NULLCP;
  479.                 dref_ptr = tmpbuf;
  480.  
  481.                 /* -- only flip valid domains -- */
  482.                 if ((ap_outtype & AP_PARSE_BIG) == AP_PARSE_BIG &&
  483.                     tb_getdomain (tmpbuf, 
  484.                           NULLCP, buf, 
  485. #ifdef UKORDER
  486.                           CH_UK_PREF,
  487. #else
  488.                           CH_USA_PREF,
  489. #endif
  490.                           &subdom) == OK) {
  491.                     /* -- usa ordering preferred -- */
  492.                     flip_ptr = ap_dmflip (buf);
  493.                     dref_ptr = flip_ptr;
  494.                 }
  495.                 if (subdom != NULLCP) {    
  496.                     free(subdom);subdom=NULLCP;
  497.                 }
  498.  
  499.                 if ((ap_outtype & AP_PARSE_822) == AP_PARSE_822 ||
  500.                     route_ptr[0] == '\0')
  501.                     /* -- easy -- */
  502.                     c_ptr = multcat (s_ptr,
  503.                              "@",
  504.                              dref_ptr,
  505.                              route_ptr,
  506.                              NULLCP);
  507.                 else
  508.                     c_ptr = multcat (s_ptr,
  509.                              "%",
  510.                              dref_ptr,
  511.                              route_ptr,
  512.                              NULLCP);
  513.  
  514.                 if (c_ptr == NULLCP)
  515.                     return (c_ptr);
  516.                 free (s_ptr);
  517.                 s_ptr = c_ptr;
  518.                 if (flip_ptr != NULLCP)
  519.                     free (flip_ptr);    
  520.                 after_comment = FALSE;
  521.                 continue;
  522.             }
  523.             break;
  524.         }
  525.     } else if (route_ptr[0] != '\0') {
  526.         c_ptr = multcat (s_ptr,
  527.                  route_ptr,
  528.                  NULLCP);
  529.  
  530.         if (c_ptr == NULLCP)
  531.             return (c_ptr);
  532.         free (s_ptr);
  533.         s_ptr = c_ptr;
  534.         after_comment = FALSE;
  535.     }
  536.  
  537.  
  538.     free (route_ptr);
  539.  
  540.     if (in_person) {
  541.         c_ptr = multcat (s_ptr, ">", NULLCP);
  542.         free (s_ptr);
  543.         if (c_ptr == NULLCP)
  544.             return ((char *)NOTOK);
  545.         s_ptr = c_ptr;
  546.         after_comment = FALSE;
  547.         if (cur_ptr != NULL && cur_ptr->ap_obtype == AP_PERSON_END)
  548.             cur_ptr = cur_ptr->ap_next;
  549.     }
  550.  
  551.     if (cur_ptr != NULL 
  552.         && cur_ptr->ap_obtype == AP_GROUP_END) {
  553.         c_ptr = multcat (s_ptr, ";", NULLCP);
  554.         free (s_ptr);
  555.         if (c_ptr == NULLCP)
  556.             return ((char *)NOTOK);
  557.         s_ptr = c_ptr;
  558.         in_group = FALSE;
  559.         cur_ptr = cur_ptr -> ap_next;
  560.     }
  561.  
  562.     if (comments == TRUE &&
  563.         cur_ptr != NULL && cur_ptr->ap_obtype == AP_COMMENT) {
  564.         while (cur_ptr != NULL 
  565.                && cur_ptr->ap_obtype == AP_COMMENT) {
  566.             /* trailing comments */
  567.             ap_val2str(tmpbuf,
  568.                    cur_ptr->ap_obvalue,
  569.                    AP_COMMENT);
  570.             c_ptr = multcat (s_ptr, 
  571.                      (s_ptr[0]?" ":""),
  572.                      "(",
  573.                      tmpbuf,
  574.                      ")",
  575.                      NULLCP);
  576.             free (s_ptr);
  577.             if (c_ptr == NULLCP)
  578.                 return ((char *) NOTOK);
  579.             s_ptr = c_ptr;
  580.             after_comment = TRUE;
  581.             cur_ptr = cur_ptr->ap_next;
  582.         }
  583.     }
  584.                 
  585.     return (s_ptr);
  586. }
  587.  
  588.  
  589. static ap_compress_local (group, name, local, domain, route, comments)
  590. AP_ptr                  group,          /* -- start of group name -- */
  591.             name,           /* -- start of person name -- */
  592.             local,          /* -- start of local-part -- */
  593.             domain,         /* -- basic domain ref -- */
  594.             route;          /* -- start of 733 forw routing -- */
  595. int            comments;
  596. {
  597.     /* compress local into one AP_ptr */
  598.     AP_ptr    ix, trc;
  599.     register char    *s_ptr,
  600.             *c_ptr;
  601.     char        tmpbuf [BUFSIZ];
  602.  
  603.     if (local == NULLAP)
  604.         return;
  605.     s_ptr = strdup("");
  606.     for (ix = local; ix != NULLAP; ix = ix -> ap_next) {
  607.         if (ix == group || ix == name ||
  608.             ix == domain || ix == route)
  609.             break;
  610.         switch (ix -> ap_obtype) {
  611.             default:
  612.             case AP_NIL:
  613.             break;
  614.  
  615.             case AP_COMMENT:
  616.             if (comments == TRUE) {
  617.                 ap_val2str (tmpbuf,
  618.                         ix -> ap_obvalue,
  619.                         AP_COMMENT);
  620.                 c_ptr = multcat (s_ptr,
  621.                          (s_ptr[0] ? " " : ""),
  622.                          "(",
  623.                          tmpbuf,
  624.                          ")",
  625.                          NULLCP);
  626.                 free(s_ptr);
  627.                 if (c_ptr == NULLCP)
  628.                     return;
  629.                 s_ptr = c_ptr;
  630.             }
  631.             continue;
  632.             
  633.             case AP_GENERIC_WORD:
  634.             case AP_MAILBOX:
  635.             /* -- yuk -- */
  636.             ap_val2str (tmpbuf,
  637.                     ix -> ap_obvalue,
  638.                     AP_MAILBOX);
  639.             c_ptr = multcat (s_ptr, 
  640.                      ((s_ptr[0] && 
  641.                        s_ptr[(strlen(s_ptr) -1)] != '"') 
  642.                       ?" ":""),
  643.                      tmpbuf, NULLCP);
  644.             free (s_ptr);
  645.             if (c_ptr == NULLCP)
  646.                 return;
  647.             s_ptr = c_ptr;
  648.             continue;
  649.         }
  650.         break;
  651.     }
  652.  
  653.     if (ix == local -> ap_next) {
  654.         /* no need to compress */
  655.         free(s_ptr);
  656.         return;
  657.     }
  658.     
  659.     for (trc = local; trc -> ap_next && trc -> ap_next != ix; ) {
  660.         switch (trc -> ap_next -> ap_obtype) {
  661.             case AP_GENERIC_WORD:
  662.             case AP_MAILBOX:
  663.             ap_delete (trc);
  664.             break;
  665.             default:
  666.             trc = trc -> ap_next;
  667.             break;
  668.         }
  669.     }
  670.  
  671.     switch (local -> ap_obtype) {
  672.         case AP_GENERIC_WORD:
  673.         case AP_MAILBOX:
  674.             free(local -> ap_obvalue);
  675.             local -> ap_obvalue = s_ptr;
  676.             break;
  677.         default:
  678.             trc = ap_alloc ();
  679.             trc -> ap_obvalue = s_ptr;
  680.             trc -> ap_obtype = AP_MAILBOX;
  681.             ap_insert (local, AP_PTR_MORE, trc);
  682.             break;
  683.     }
  684. }
  685.